home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PRINTER / JPSRC11.ARJ / JETDMP.C < prev    next >
C/C++ Source or Header  |  1991-08-04  |  26KB  |  625 lines

  1. /*
  2.  *      JET PAK - HP DeskJet and LaserJet series printer utilities
  3.  *
  4.  *      JETDMP program - output symbolic dump of soft font file
  5.  *
  6.  *      Version 1.1 (Public Domain)
  7.  */
  8.  
  9. /* system include files */
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <ctype.h>
  14.  
  15. /* application include files */
  16. #include "patchlev.h"
  17. #include "jetfont.h"
  18. #include "jetmean.h"
  19. #include "jetutil.h"
  20. #include "jetbmp.h"
  21.  
  22. /* macro to print out first three descriptor table fields derived/forced */
  23. #define _PFD(field)  field,(loc=nloc,nloc+=sizeof(field),loc),sizeof(field)
  24. #define _PFF(field,val)     field,(loc=nloc,nloc+=val,loc),val
  25.  
  26. /*
  27.  * MODULE GLOBAL DATA
  28.  */
  29.  
  30. /* baseline distance for bottom pass */
  31. static UNSIGNEDINT baseline;
  32.  
  33. /* portrait or landscape font */
  34. static UNSIGNEDBYTE orientation;
  35.  
  36. /* scratch area for decompressed DJ bitmap */
  37. static char scratch[BITMAP_SIZE_MAX];
  38.  
  39. /* font command being processed */
  40. static FONT_COMMAND fc;
  41.  
  42. /* character code being processed */
  43. static UNSIGNEDINT charcode;
  44.  
  45. /* suffix for output file */
  46. static char output_suffix[SUFFIX_MAX] = ".dmp";
  47.  
  48. /*
  49.  * LOCAL FUNCTIONS
  50.  */
  51.  
  52. static void usage_wrong()
  53. {
  54.     /*
  55.      * Print usage message and exit.
  56.      */
  57.     fprintf(stderr, USAGE_HEADER);
  58.     fprintf(stderr, "Usage: JETDMP [-h] [-t filetype] fontfile [fontfile...]\n\n");
  59.     fprintf(stderr, "Dump symbolic listings for soft fonts\n\n");
  60.     fprintf(stderr, "  -h            print this usage information\n");
  61.     fprintf(stderr, "  -t filetype   change output file type (default %s)\n", output_suffix);
  62.     fprintf(stderr, "  fontfile      soft font file name\n");
  63.     exit(1);
  64. }
  65.  
  66. static int buffer_dump(fp, buf, len)
  67. FILE *fp;
  68. char *buf;
  69. int len;
  70. {
  71.     /*
  72.      * Dump a buffer, escaping '\' and '"' as necessary
  73.      */
  74.  
  75.     if (putc('"', fp) < 0)
  76.         return(ERROR);
  77.  
  78.     while (len-- > 0)
  79.     {
  80.         if (*buf == '\\' || *buf == '"')
  81.             if (putc('\\', fp) < 0)
  82.                 return(ERROR);
  83.  
  84.         if (putc(*buf, fp) < 0)
  85.             return(ERROR);
  86.  
  87.         buf++;
  88.     }
  89.  
  90.     if (putc('"', fp) < 0)
  91.         return(ERROR);
  92.  
  93.     return(OK);
  94. }
  95.  
  96. static int filename_dump(fp, sp)
  97. FILE *fp;
  98. char *sp;
  99. {
  100.     /*
  101.      * Dump a filename record
  102.      */
  103.  
  104.     if (fprintf(fp, "%s ", KEYWORD_FILE) < 0) return(ERROR);
  105.     if (buffer_dump(fp, sp, strlen(sp)) == ERROR) return(ERROR);
  106.     if (fprintf(fp, "\n") < 0) return(ERROR);
  107.  
  108.     return(OK);
  109. }
  110.  
  111. static int header_dump(fp)
  112. FILE *fp;
  113. {
  114.     /*
  115.      * Dump the font descriptor header record
  116.      */
  117.     int loc, nloc = 0;
  118.     char name_combined[sizeof(fc.data.font.name)+sizeof(fc.data.font.name_extension)];
  119.  
  120.     if (fprintf(fp, "\n%s\n", KEYWORD_HEADER) < 0) return(ERROR);
  121.     if (fprintf(fp, "\n#          Key to HEADER information:\n") < 0) return(ERROR);
  122.     if (fprintf(fp, "#\n") < 0) return(ERROR);
  123.     if (fprintf(fp, "# Value    Loc   Size  Type  Name               Units/meaning\n") < 0) return(ERROR);
  124.     if (fprintf(fp, "#\n") < 0) return(ERROR);
  125.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Descriptor Size    Bytes\n",    _PFD(fc.data.font.size)) < 0) return(ERROR);
  126.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UB    Header Format      %s\n",       _PFD(fc.data.font.header_format), header_format_meaning(fc.data.font.header_format)) < 0) return(ERROR);
  127.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UB    Font Type          %s\n",       _PFD(fc.data.font.type), font_type_meaning(fc.data.font.type)) < 0) return(ERROR);
  128.     if (fprintf(fp, "  %-6u # %-4d  %-4d        Reserved           \n",         _PFD(fc.data.font.reserved1)) < 0) return(ERROR);
  129.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Baseline Distance  Dots\n",     _PFD(fc.data.font.baseline_distance)) < 0) return(ERROR);
  130.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Cell Width         Dots\n",     _PFD(fc.data.font.cell_width)) < 0) return(ERROR);
  131.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Cell Height        Dots\n",     _PFD(fc.data.font.cell_height)) < 0) return(ERROR);
  132.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UB    Orientation        %s\n",       _PFD(fc.data.font.orientation), orientation_meaning(fc.data.font.orientation)) < 0) return(ERROR);
  133.     if (fprintf(fp, "  %-6u # %-4d  %-4d  B     Spacing            %s\n",       _PFD(fc.data.font.spacing), spacing_meaning(fc.data.font.spacing)) < 0) return(ERROR);
  134.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Symbol Set         %s\n",       _PFD(fc.data.font.symbol_set), symbol_set_meaning(fc.data.font.symbol_set)) < 0) return(ERROR);
  135.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Pitch              1/4 Dots\n", _PFD(fc.data.font.pitch)) < 0) return(ERROR);
  136.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Height             1/4 Dots\n", _PFD(fc.data.font.height)) < 0) return(ERROR);
  137.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    x Height           1/4 Dots\n", _PFD(fc.data.font.x_height)) < 0) return(ERROR);
  138.     if (fprintf(fp, "  %-6d # %-4d  %-4d  SB    Width Type         %s\n",       _PFD(fc.data.font.width_type), width_type_meaning(fc.data.font.width_type)) < 0) return(ERROR);
  139.     if (fc.data.font.header_format == DJ500FONTFORMAT)
  140.     {
  141.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Style              %s\n",       _PFD(fc.data.font.style), style_meaning(fc.data.font.style)) < 0) return(ERROR);
  142.     }
  143.     else
  144.     {
  145.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UB    Style              %s\n",       _PFF(fc.data.font.style,1), style_meaning(fc.data.font.style)) < 0) return(ERROR);
  146.     }
  147.     if (fprintf(fp, "  %-6d # %-4d  %-4d  SB    Stroke Weight      %s\n",       _PFD(fc.data.font.stroke_weight), stroke_weight_meaning(fc.data.font.stroke_weight)) < 0) return(ERROR);
  148.     if (fc.data.font.header_format == DJ500FONTFORMAT)
  149.     {
  150.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Typeface           %s\n",       _PFD(fc.data.font.typeface), typeface_meaning(fc.data.font.typeface)) < 0) return(ERROR);
  151.     }
  152.     else
  153.     {
  154.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UB    Typeface           %s\n",       _PFF(fc.data.font.typeface,1), typeface_meaning(fc.data.font.typeface)) < 0) return(ERROR);
  155.     }
  156.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UB    Slant              \n",         _PFD(fc.data.font.slant)) < 0) return(ERROR);
  157.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UB    Serif Style        %s\n",       _PFD(fc.data.font.serif_style), serif_style_meaning(fc.data.font.serif_style)) < 0) return(ERROR);
  158.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UB    Quality            %s\n",       _PFD(fc.data.font.quality), quality_meaning(fc.data.font.quality)) < 0) return(ERROR);
  159.     if (fprintf(fp, "  %-6d # %-4d  %-4d  SB    Placement          %s\n",       _PFD(fc.data.font.placement), placement_meaning(fc.data.font.placement)) < 0) return(ERROR);
  160.     if (fprintf(fp, "  %-6d # %-4d  %-4d  SB    Underline distance Dots\n",     _PFD(fc.data.font.underline_distance)) < 0) return(ERROR);
  161.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UB    Underline height   Dots\n",     _PFD(fc.data.font.underline_height)) < 0) return(ERROR);
  162.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Text Height        1/4 Dots\n", _PFD(fc.data.font.text_height)) < 0) return(ERROR);
  163.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Text Width         1/4 Dots\n", _PFD(fc.data.font.text_width)) < 0) return(ERROR);
  164.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    First Code         \n",         _PFD(fc.data.font.first_code)) < 0) return(ERROR);
  165.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Last Code          \n",         _PFD(fc.data.font.last_code)) < 0) return(ERROR);
  166.     if (fprintf(fp, "  %-6u # %-4d  %-4d  EB    Extended Pitch     \n",         _PFD(fc.data.font.pitch_extended)) < 0) return(ERROR);
  167.     if (fprintf(fp, "  %-6u # %-4d  %-4d  EB    Extended Height    \n",         _PFD(fc.data.font.height_extended)) < 0) return(ERROR);
  168.     if (fprintf(fp, "  %-6u # %-4d  %-4d        Reserved           \n",         _PFD(fc.data.font.reserved2)) < 0) return(ERROR);
  169.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Font Number Top    \n",         _PFD(fc.data.font.font_number_top)) < 0) return(ERROR);
  170.     if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Font Number Bottom \n",         _PFD(fc.data.font.font_number_bot)) < 0) return(ERROR);
  171.  
  172.     /* adjust for font name size (output out of sync, at the end) */
  173.     nloc += sizeof(fc.data.font.name);
  174.  
  175.     if (fc.data.font.size > LJFDSIZE)
  176.     {
  177.         if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    H pixel resolution Dots/Inch\n", _PFD(fc.data.font.h_pixel_resolution)) < 0) return(ERROR);
  178.         if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    V pixel resolution Dots/Inch\n", _PFD(fc.data.font.v_pixel_resolution)) < 0) return(ERROR);
  179.         if (fprintf(fp, "  %-6d # %-4d  %-4d  SB    Top Dbl Und Dist   Dots\n",      _PFD(fc.data.font.tdu_distance)) < 0) return(ERROR);
  180.         if (fprintf(fp, "  %-6u # %-4d  %-4d  UB    Top Dbl Und Height Dots\n",      _PFD(fc.data.font.tdu_height)) < 0) return(ERROR);
  181.         if (fprintf(fp, "  %-6d # %-4d  %-4d  SB    Bot Dbl Und Dist   Dots\n",      _PFD(fc.data.font.bdu_distance)) < 0) return(ERROR);
  182.         if (fprintf(fp, "  %-6u # %-4d  %-4d  UB    Bot Dbl Und Height Dots\n",      _PFD(fc.data.font.bdu_height)) < 0) return(ERROR);
  183.         if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Printer Desc Size  Bytes\n",     _PFD(fc.data.font.specific_size)) < 0) return(ERROR);
  184.         if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Font Data Size     \n",          _PFD(fc.data.font.data_size)) < 0) return(ERROR);
  185.         if (fprintf(fp, "  %-6u # %-4d  %-4d  B     Unidirectional?    %s\n",        _PFD(fc.data.font.unidirection), boolean_meaning(fc.data.font.unidirection)) < 0) return(ERROR);
  186.         if (fprintf(fp, "  %-6u # %-4d  %-4d  B     Compressed Info?   %s\n",        _PFD(fc.data.font.compressed), boolean_meaning(fc.data.font.compressed)) < 0) return(ERROR);
  187.         if (fprintf(fp, "  %-6u # %-4d  %-4d  UB    Hold Time Factor   Relative\n",  _PFD(fc.data.font.hold_time_factor)) < 0) return(ERROR);
  188.         if (fprintf(fp, "  %-6u # %-4d  %-4d  B     No Half Pitch?     %s\n",        _PFD(fc.data.font.no_half_pitch), boolean_meaning(fc.data.font.no_half_pitch)) < 0) return(ERROR);
  189.         if (fprintf(fp, "  %-6u # %-4d  %-4d  B     No Double Pitch?   %s\n",        _PFD(fc.data.font.no_double_pitch), boolean_meaning(fc.data.font.no_double_pitch)) < 0) return(ERROR);
  190.         if (fprintf(fp, "  %-6u # %-4d  %-4d  B     No Half Height?    %s\n",        _PFD(fc.data.font.no_half_height), boolean_meaning(fc.data.font.no_half_height)) < 0) return(ERROR);
  191.         if (fprintf(fp, "  %-6u # %-4d  %-4d  B     No Bold?           %s\n",        _PFD(fc.data.font.no_bold), boolean_meaning(fc.data.font.no_bold)) < 0) return(ERROR);
  192.         if (fprintf(fp, "  %-6u # %-4d  %-4d  B     No Draft?          %s\n",        _PFD(fc.data.font.no_draft), boolean_meaning(fc.data.font.no_draft)) < 0) return(ERROR);
  193.         if (fprintf(fp, "  %-6u # %-4d  %-4d  B     Dark Bold Method?  %s\n",        _PFD(fc.data.font.bold_method), boolean_meaning(fc.data.font.bold_method)) < 0) return(ERROR);
  194.         if (fprintf(fp, "  %-6u # %-4d  %-4d        Reserved           \n",          _PFD(fc.data.font.reserved3)) < 0) return(ERROR);
  195.         if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Baseline Offset 2  Dots\n",      _PFD(fc.data.font.baseline_offset_2)) < 0) return(ERROR);
  196.         if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Baseline Offset 3  Dots\n",      _PFD(fc.data.font.baseline_offset_3)) < 0) return(ERROR);
  197.         if (fprintf(fp, "  %-6u # %-4d  %-4d  UI    Baseline Offset 4  Dots\n",      _PFD(fc.data.font.baseline_offset_4)) < 0) return(ERROR);
  198.     }
  199.  
  200.     if (fc.data.font.header_format == DJ500FONTFORMAT)
  201.     {
  202.         /* print out combined name and name extension for DJ500 only */
  203.         strncpy(name_combined, fc.data.font.name, sizeof(fc.data.font.name));
  204.         strncpy(name_combined+sizeof(fc.data.font.name), fc.data.font.name_extension, sizeof(fc.data.font.name_extension));
  205.  
  206.         if (fprintf(fp, "\n%s ", KEYWORD_NAME) < 0) return(ERROR);
  207.         if (buffer_dump(fp, name_combined, sizeof(name_combined)) == ERROR) return(ERROR);
  208.         if (fprintf(fp, "\n") < 0) return(ERROR);
  209.     }
  210.     else
  211.     {
  212.         if (fprintf(fp, "\n%s ", KEYWORD_NAME) < 0) return(ERROR);
  213.         if (buffer_dump(fp, fc.data.font.name, sizeof(fc.data.font.name)) == ERROR) return(ERROR);
  214.         if (fprintf(fp, "\n") < 0) return(ERROR);
  215.     }
  216.  
  217.     if (fprintf(fp, "\n%s ", KEYWORD_COMMENT) < 0) return(ERROR);
  218.     if (buffer_dump(fp, fc.data.font.comment, strlen(fc.data.font.comment)) == ERROR) return(ERROR);
  219.     if (fprintf(fp, "\n") < 0) return(ERROR);
  220.  
  221.     /* print key to the character descriptor information */
  222.     switch (fc.data.font.header_format)
  223.     {
  224.     default:
  225.         fprintf(stderr, WARNING_BAD_FONT_FORMAT,
  226.                     os_dir, os_file, fc.data.font.header_format);
  227.  
  228.         /* !! INTENTIONAL DROP-THROUGH !! */
  229.  
  230.     case LJFONTFORMAT:
  231.         if (fprintf(fp, "\n#        Key to CHAR information:\n") < 0) return(ERROR);
  232.         if (fprintf(fp, "#\n") < 0) return(ERROR);
  233.         if (fprintf(fp, "# Tag    Loc   Size  Type  Name               Units/meaning\n") < 0) return(ERROR);
  234.         if (fprintf(fp, "#\n") < 0) return(ERROR);
  235.         if (fprintf(fp, "# Form   0     1     UB    Format             4=LJ\n") < 0) return(ERROR);
  236.         if (fprintf(fp, "# Cont   1     1     B     Is contination?    0=No,1=Yes\n") < 0) return(ERROR);
  237.         if (fprintf(fp, "# Dsiz   2     1     UB    Descriptor size    Bytes\n") < 0) return(ERROR);
  238.         if (fprintf(fp, "# Clas   3     1     UB    Class              1=LJ\n") < 0) return(ERROR);
  239.         if (fprintf(fp, "# Orie   4     1     UB    Orientation        0=Portr,1=Lands\n") < 0) return(ERROR);
  240.         if (fprintf(fp, "# Rese   5     1           Reserved           \n") < 0) return(ERROR);
  241.         if (fprintf(fp, "# Loffst 6     2     SI    Left offset        Dots\n") < 0) return(ERROR);
  242.         if (fprintf(fp, "# Toffst 8     2     SI    Top offset         Dots\n") < 0) return(ERROR);
  243.         if (fprintf(fp, "# Cwidth 10    2     UI    Character width    Dots\n") < 0) return(ERROR);
  244.         if (fprintf(fp, "# Chght  12    2     UI    Character height   Dots\n") < 0) return(ERROR);
  245.         if (fprintf(fp, "# DeltaX 14    2     SI    Delta X            1/4 Dots\n") < 0) return(ERROR);
  246.         break;
  247.     case DJFONTFORMAT:
  248.     case DJPFONTFORMAT:
  249.     case DJ500FONTFORMAT:
  250.         if (fprintf(fp, "\n#        Key to CHAR information:\n") < 0) return(ERROR);
  251.         if (fprintf(fp, "#\n") < 0) return(ERROR);
  252.         if (fprintf(fp, "# Tag    Loc   Size  Type  Name               Units/meaning\n") < 0) return(ERROR);
  253.         if (fprintf(fp, "#\n") < 0) return(ERROR);
  254.         if (fprintf(fp, "# Form   0     1     UB    Format             5=DJ,9=DJ+\n") < 0) return(ERROR);
  255.         if (fprintf(fp, "# Cont   1     1     UB    Is contination?    0=No,1=Yes\n") < 0) return(ERROR);
  256.         if (fprintf(fp, "# Dsiz   2     1     UB    Descriptor size    Bytes\n") < 0) return(ERROR);
  257.         if (fprintf(fp, "# Type   3     1     UB    Character type     0=Single Pass,2-5=Multi Pass\n") < 0) return(ERROR);
  258.         if (fprintf(fp, "# Wdth   4     1     UB    Character width    Dots\n") < 0) return(ERROR);
  259.         if (fprintf(fp, "# Cwdt   5     1     UB    Compressed width   Dots\n") < 0) return(ERROR);
  260.         if (fprintf(fp, "# Lpad   6     1     SB/UB Left pad           Dots\n") < 0) return(ERROR);
  261.         if (fprintf(fp, "# Rpad   7     1     SB/UB Right pad          Dots\n") < 0) return(ERROR);
  262.         break;
  263.     }
  264.  
  265.     /* save baseline and orientation for bitmap marking */
  266.     baseline = fc.data.font.baseline_distance;
  267.     orientation = fc.data.font.orientation;
  268.  
  269.     return(OK);
  270. }
  271.  
  272. static int character_dump(fp)
  273. FILE *fp;
  274. {
  275.     /*
  276.      * Dump a character descriptor record
  277.      */
  278.  
  279.     if (fprintf(fp, "\n%s\n\n", KEYWORD_CHAR) < 0)
  280.         return(ERROR);
  281.  
  282.     if (isascii(charcode) && isprint(charcode))
  283.     {
  284.         if (fprintf(fp, "# %c    ", charcode) < 0)
  285.             return(ERROR);
  286.     }
  287.     else
  288.     {
  289.         if (fprintf(fp, "# \\%03o ", charcode) < 0)
  290.             return(ERROR);
  291.     }
  292.  
  293.     switch (fc.data.character.format)
  294.     {
  295.     default:
  296.         fprintf(stderr, WARNING_BAD_CHAR_FORMAT,
  297.                     os_dir, os_file, fc.data.character.format);
  298.  
  299.         /* !! INTENTIONAL DROP-THROUGH !! */
  300.  
  301.     case LJCHARFORMAT:
  302.         if (fprintf(fp, "Form Cont Dsiz Clas Orie Rese Loffst Toffst Cwidth Chght  DeltaX\n") < 0)
  303.             return(ERROR);
  304.  
  305.         if (fprintf(fp, "  %-4u %-4u %-4u %-4u %-4u %-4u %-4u %-6d %-6d %-6u %-6u %-6d\n",
  306.                 charcode,
  307.                 fc.data.character.format,
  308.                 fc.data.character.continuation,
  309.                 fc.data.character.data.ljchar.descriptor_size,
  310.                 fc.data.character.data.ljchar.class,
  311.                 fc.data.character.data.ljchar.orientation,
  312.                 fc.data.character.data.ljchar.reserved,
  313.                 fc.data.character.data.ljchar.left_offset,
  314.                 fc.data.character.data.ljchar.top_offset,
  315.                 fc.data.character.data.ljchar.character_width,
  316.                 fc.data.character.data.ljchar.character_height,
  317.                 fc.data.character.data.ljchar.delta_x) < 0)
  318.             return(ERROR);
  319.         break;
  320.  
  321.     case DJCHARFORMAT:
  322.     case DJPCHARFORMAT:
  323.     case DJ500CHARFORMAT:
  324.         if (fprintf(fp, "Form Cont Dsiz Type Wdth Cwdt Lpad Rpad\n") < 0)
  325.             return(ERROR);
  326.  
  327.         if (fprintf(fp, "  %-4u %-4u %-4u %-4u %-4u %-4u %-4u %-4d %-4d\n",
  328.                 charcode,
  329.                 fc.data.character.format,
  330.                 fc.data.character.continuation,
  331.                 fc.data.character.data.djchar.descriptor_size,
  332.                 fc.data.character.data.djchar.char_type,
  333.                 fc.data.character.data.djchar.character_width,
  334.                 fc.data.character.data.djchar.comp_width,
  335.                 fc.data.character.data.djchar.left_offset,
  336.                 fc.data.character.data.djchar.right_offset) < 0)
  337.             return(ERROR);
  338.         break;
  339.     }
  340.  
  341.     return(OK);
  342. }
  343.  
  344. static int bitmap_dump(fp, bp, cw, ch, baseline)
  345. FILE *fp;
  346. register UNSIGNEDBYTE *bp;
  347. UNSIGNEDINT cw, ch;
  348. SIGNEDINT baseline;
  349. {
  350.     /*
  351.      * Dump a bitmap record
  352.      */
  353.     register UNSIGNEDINT pmask;
  354.     UNSIGNEDINT x;
  355.     UNSIGNEDBYTE *saved_bp;
  356.     UNSIGNEDINT ow;
  357.  
  358.     if (fprintf(fp, "\n%s\n\n", KEYWORD_BITMAP) < 0)
  359.         return(ERROR);
  360.  
  361.     if (orientation == LANDSCAPE)
  362.     {
  363.         if (baseline < 0)
  364.             while (++baseline != 0)
  365.                 if (putc(' ', fp) < 0)
  366.                     return(ERROR);
  367.  
  368.         if (fprintf(fp, "#<-BASELINE\n") < 0)
  369.             return(ERROR);
  370.     }
  371.  
  372.     while (ch-- > 0)
  373.     {
  374.         /* make one pass through the line to find rightmost set dot */
  375.         saved_bp = bp;
  376.         ow = 0;
  377.         for (x = 0, pmask = 0x80; x < cw; x++, pmask >>= 1)
  378.         {
  379.             if (pmask == 0)
  380.             {
  381.                 pmask = 0x80;
  382.                 bp++;
  383.             }
  384.  
  385.             if (*bp & pmask)
  386.                 ow = x;
  387.         }
  388.  
  389.         /* print bitmap omitting clear dots to right of set dots: the
  390.            exception is that one clear dot is printed for completely
  391.            clear lines so the token isn't lost!! */
  392.         bp = saved_bp;
  393.         for (x = 0, pmask = 0x80; x < cw; x++, pmask >>= 1)
  394.         {
  395.             if (pmask == 0)
  396.             {
  397.                 pmask = 0x80;
  398.                 bp++;
  399.             }
  400.  
  401.             if (*bp & pmask)
  402.             {
  403.                 if (putc('@', fp) < 0)
  404.                     return(ERROR);
  405.             }
  406.             else if (x <= ow)
  407.             {
  408.                 if (putc('.', fp) < 0)
  409.                     return(ERROR);
  410.             }
  411.         }
  412.         bp++;
  413.  
  414.         if (orientation == PORTRAIT)
  415.         {
  416.             /* mark the baseline position */
  417.             if (--baseline == 0)
  418.                 if (fprintf(fp, " # __BASELINE__") < 0)
  419.                     return(ERROR);
  420.         }
  421.  
  422.         if (putc('\n', fp) < 0)
  423.             return(ERROR);
  424.     }
  425.  
  426.     return(OK);
  427. }
  428.  
  429. static void jetdmp()
  430. {
  431.     /*
  432.      * Dump a complete soft font file
  433.      */
  434.     char inpath[OS_PATH_LEN], outpath[OS_PATH_LEN], *sp;
  435.     FILE *infp, *outfp;
  436.     SIGNEDINT offset;
  437.     int r, fdc_found = FALSE;
  438.  
  439.     /* build the input and output file paths */
  440.     strcpy(inpath, os_dir);
  441.     strcat(inpath, os_file);
  442.     strcpy(outpath, os_file);
  443.     if ((sp = strrchr(outpath, '.')) == NULL)
  444.         strcat(outpath, output_suffix);
  445.     else
  446.         strcpy(sp, output_suffix);
  447.  
  448.     /* rudimentary check for input overwriting output */
  449.     if (strcmp(inpath, outpath) == 0)
  450.     {
  451.         fprintf(stderr, ERROR_OVERWRITE, os_dir, os_file);
  452.         return;
  453.     }
  454.  
  455.     if (!(infp = fopen(inpath, "rb")))
  456.     {
  457.         fprintf(stderr, ERROR_OPEN_READ_FAILED, os_dir, os_file);
  458.         return;
  459.     }
  460.     if (!(outfp = fopen(outpath, "w")))
  461.     {
  462.         fprintf(stderr, ERROR_OPEN_WRITE_FAILED, os_dir, os_file, outpath);
  463.         fclose(infp);
  464.         return;
  465.     }
  466.  
  467.     if (filename_dump(outfp, os_file) == ERROR)
  468.     {
  469.         fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
  470.         fclose(infp);
  471.         fclose(outfp);
  472.         return;
  473.     }
  474.  
  475.     while ((r = font_command_read(infp, &fc)) == OK)
  476.     {
  477.         switch(fc.command_type)
  478.         {
  479.         case FDC:
  480.             if (header_dump(outfp) == ERROR)
  481.             {
  482.                 fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
  483.                 fclose(infp);
  484.                 fclose(outfp);
  485.                 return;
  486.             }
  487.  
  488.             fdc_found = TRUE;
  489.  
  490.             break;
  491.         case CCC:
  492.             charcode = fc.number;
  493.             break;
  494.         case CDC:
  495.             if (character_dump(outfp) == ERROR)
  496.             {
  497.                 fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
  498.                 fclose(infp);
  499.                 fclose(outfp);
  500.                 return;
  501.             }
  502.  
  503.             switch(fc.data.character.format)
  504.             {
  505.             default:
  506.  
  507.                 /* !! INTENTIONAL DROP-THROUGH */
  508.  
  509.             case LJCHARFORMAT:
  510.                 /* get offset to baseline mark */
  511.                 if (orientation == PORTRAIT)
  512.                     offset = fc.data.character.data.ljchar.top_offset;
  513.                 else
  514.                     offset = fc.data.character.data.ljchar.left_offset;
  515.  
  516.                 if (bitmap_dump(outfp,
  517.                     fc.data.character.data.ljchar.bitmap,
  518.                     fc.data.character.data.ljchar.character_width,
  519.                     fc.data.character.data.ljchar.character_height,
  520.                     offset) == ERROR)
  521.                 {
  522.                     fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
  523.                     fclose(infp);
  524.                     fclose(outfp);
  525.                     return;
  526.                 }
  527.  
  528.                 break;
  529.             case DJCHARFORMAT:
  530.             case DJPCHARFORMAT:
  531.             case DJ500CHARFORMAT:
  532.                 /* get offset to baseline mark */
  533.                 if (orientation == PORTRAIT)
  534.                 {
  535.                     if (pass_for_char_type(fc.data.character.data.djchar.char_type) == 0)
  536.                         offset = (SIGNEDINT)baseline;
  537.                     else
  538.                         offset = (SIGNEDINT)PASS_HEIGHT+1;
  539.                 }
  540.                 else
  541.                 {
  542.                     offset = ((SIGNEDINT)fc.data.character.data.djchar.comp_width) - 2*(SIGNEDINT)baseline;
  543.                 }
  544.  
  545.                 if (bitmap_decompress(fc.data.character.data.djchar.bitmap,
  546.                     fc.data.character.data.djchar.character_width,
  547.                     PASS_HEIGHT, scratch, sizeof(scratch)) == ERROR)
  548.                 {
  549.                     fprintf(stderr, ERROR_BITMAP_TOO_BIG, os_dir, os_file);
  550.                     fclose(infp);
  551.                     fclose(outfp);
  552.                     return;
  553.                 }
  554.  
  555.                 if (bitmap_dump(outfp, scratch,
  556.                        fc.data.character.data.djchar.character_width,
  557.                        PASS_HEIGHT, offset) == ERROR)
  558.                 {
  559.                     fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
  560.                     fclose(infp);
  561.                     fclose(outfp);
  562.                     return;
  563.                 }
  564.  
  565.                 break;
  566.             }
  567.             break;
  568.         }
  569.     }
  570.  
  571.  
  572.     /* error scenarios: (!fdc_found) means no font descriptor found,
  573.        probably processing a text file; (r != EOF) means a font
  574.        command escape sequence wasn't read in correctly, probably
  575.        processing a binary file or a truncated soft font file */
  576.     if (!fdc_found || r != EOF)
  577.         fprintf(stderr, ERROR_FILE_READ_FAILED, os_dir, os_file);
  578.     else
  579.         fprintf(stderr, OK_JETDMP, os_dir, os_file, outpath);
  580.  
  581.     fclose(infp);
  582.     fclose(outfp);
  583. }
  584.  
  585. /*
  586.  *  EXTERNAL FUNCTION
  587.  */
  588.  
  589. int main(argc, argv)
  590. int argc;
  591. char *argv[];
  592. {
  593.     char c;
  594.  
  595.     /* stop getopt() printing errors */
  596.     opterr = FALSE;
  597.     while ((c = getopt(argc, argv, "t:h")) != EOF)
  598.     {
  599.         switch (c)
  600.         {
  601.         case 't':
  602.             strncpy(output_suffix+1, optarg, SUFFIX_MAX-2);
  603.             output_suffix[SUFFIX_MAX-1] = '\0';
  604.             break;
  605.         case 'h':
  606.         case '?':
  607.             /* help required, or invalid option specified */
  608.             usage_wrong();
  609.         }
  610.     }
  611.  
  612.     /* must specify at least one file */
  613.     if (optind >= argc)
  614.         usage_wrong();
  615.  
  616.     /* process file arguments */
  617.     if (os_findfiles((argc - optind), &argv[optind]) == ERROR)
  618.         fprintf(stderr, ERROR_OUT_OF_HEAP);
  619.  
  620.     while (os_getfile() != EOF)
  621.         jetdmp();
  622.  
  623.     return(0);
  624. }
  625.